<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="Directory.Build.props" />

  <Target Name="ResolveDisabledProjects" BeforeTargets="BuildAllProjects;CopyAllNativeTestProjectBinaries" >
    <PropertyGroup>
      <TestRoot>$(RepoRoot)src\tests\</TestRoot>
    </PropertyGroup>

    <ItemGroup>
      <DisabledProjects Include="$(TestRoot)*\**\cs_template.csproj" />
      <DisabledProjects Include="$(TestRoot)Common\**\*.*proj" />
      <DisabledProjects Include="$(TestRoot)FunctionalTests\**\*.csproj" /> <!-- They need to be isolated from the existing setup -->
      <DisabledProjects Include="$(TestRoot)GC\Performance\Framework\GCPerfTestFramework.csproj" />
      <DisabledProjects Include="$(TestRoot)Loader\classloader\StaticVirtualMethods\**\generatetest.csproj" /> <!-- test generators -->
      <DisabledProjects Include="$(TestRoot)Performance\Scenario\JitBench\unofficial_dotnet\JitBench.csproj" /> <!-- no official build support for SDK-style netcoreapp2.0 projects -->
      <DisabledProjects Include="$(TestRoot)TestWrappers*\**\*.csproj" />
      <DisabledProjects Include="$(TestRoot)nativeaot\**\*.csproj" Condition="'$(TestBuildMode)' != 'nativeaot'" />
      <DisabledProjects Include="$(TestRoot)readytorun\**\*.csproj" Condition="'$(TestBuildMode)' == 'nativeaot'" />
    </ItemGroup>

    <ItemGroup>
      <BuildTestProjects Include="$(__BuildTestProject.Split(';'))" />
      <BuildTestDirs Include="$(__BuildTestDir.Split(';'))" />
      <BuildTestTrees Include="$(__BuildTestTree.Split(';'))" />
    </ItemGroup>

    <ItemGroup Condition="'@(BuildTestProjects)' != ''">
      <AllProjects Include="$([MSBuild]::NormalizePath('$(TestRoot)', '%(BuildTestProjects.Identity)'))" Exclude="@(DisabledProjects)" />
    </ItemGroup>

    <ItemGroup Condition="'@(BuildTestDirs)' != ''">
      <AllProjects Include="$([MSBuild]::NormalizeDirectory('$(TestRoot)', '%(BuildTestDirs.Identity)'))\*.csproj" Exclude="@(DisabledProjects)" />
      <AllProjects Include="$([MSBuild]::NormalizeDirectory('$(TestRoot)', '%(BuildTestDirs.Identity)'))\*.fsproj" Exclude="@(DisabledProjects)" />
      <AllProjects Include="$([MSBuild]::NormalizeDirectory('$(TestRoot)', '%(BuildTestDirs.Identity)'))\*.ilproj" Exclude="@(DisabledProjects)" />
    </ItemGroup>

    <ItemGroup Condition="'@(BuildTestTrees)' != ''">
      <AllProjects Include="$([MSBuild]::NormalizeDirectory('$(TestRoot)', '%(BuildTestTrees.Identity)'))\**\*.csproj" Exclude="@(DisabledProjects)" />
      <AllProjects Include="$([MSBuild]::NormalizeDirectory('$(TestRoot)', '%(BuildTestTrees.Identity)'))\**\*.fsproj" Exclude="@(DisabledProjects)" />
      <AllProjects Include="$([MSBuild]::NormalizeDirectory('$(TestRoot)', '%(BuildTestTrees.Identity)'))\**\*.ilproj" Exclude="@(DisabledProjects)" />
    </ItemGroup>

    <ItemGroup Condition="'@(BuildTestProjects)' == '' and '@(BuildTestDirs)' == '' and '@(BuildTestTrees)' == ''">
      <AllProjects Include="$(TestRoot)**\*.csproj" Exclude="@(DisabledProjects)" />
      <AllProjects Include="$(TestRoot)**\*.fsproj" Exclude="@(DisabledProjects)" />
      <AllProjects Include="$(TestRoot)**\*.ilproj" Exclude="@(DisabledProjects)" />
    </ItemGroup>
    <!-- All the test projects are partitioned into the test groups as defined below.
         Each of the test groups is meant to be built by a separate MSBuild invocation with specified $(__TestGroupToBuild) property. -->
    <ItemGroup Condition=" '$(CLRTestPriorityToBuild)' == '0' ">

      <!-- Fast filter to avoid files with Pri1 projects, this isn't completely accurate, but its close. Any Pri1 tests not caught by this will be skipped,
           and any tests intended as Pri0 will end up running as Pri1, which isn't terrible. This trick allows us to avoid loading each project into msbuild
           and evaluating it, which is a substantial improvement to the performance of the "Copy native test components to test output folder" task in our test runs  -->
      <Pri1Projects Include="@(AllProjects)" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch($([System.IO.File]::ReadAllText('%(AllProjects.FullPath)')), '&lt;CLRTestPriority&gt;1&lt;/CLRTestPriority&gt;'))" />

      <AllProjects Remove="@(Pri1Projects)" />

      <!-- Group number k consists of all the test projects P such that _GroupStartsWith(k) <= P.Identity < _GroupStartsWith(k+1).
           In other words, ItemGroup _GroupStartsWith defines boundaries between the test groups. -->

      <!-- MSBuild does not allow specifying an item with empty identity but if it was possible Group number 1 would be defined as follows:

      <_GroupStartsWith Include="">
        <GroupNumber>1</GroupNumber>
      </_GroupStartsWith> -->

      <_GroupStartsWith Include="$(TestRoot)JIT\Methodical">
        <GroupNumber>2</GroupNumber>
      </_GroupStartsWith>

      <_GroupStartsWith Include="$(TestRoot)JIT\Regression">
        <GroupNumber>3</GroupNumber>
      </_GroupStartsWith>
    </ItemGroup>

    <ItemGroup Condition=" '$(CLRTestPriorityToBuild)' == '1' ">
      <!-- See above for explanation.
      <_GroupStartsWith Include="">
        <GroupNumber>1</GroupNumber>
      </_GroupStartsWith> -->

      <_GroupStartsWith Include="$(TestRoot)Interop">
        <GroupNumber>2</GroupNumber>
      </_GroupStartsWith>

      <_GroupStartsWith Include="$(TestRoot)JIT\Directed">
        <GroupNumber>3</GroupNumber>
      </_GroupStartsWith>

      <_GroupStartsWith Include="$(TestRoot)JIT\IL_Conformance">
        <GroupNumber>4</GroupNumber>
      </_GroupStartsWith>

      <_GroupStartsWith Include="$(TestRoot)JIT\Methodical">
        <GroupNumber>5</GroupNumber>
      </_GroupStartsWith>

      <_GroupStartsWith Include="$(TestRoot)JIT\Methodical\flowgraph">
        <GroupNumber>6</GroupNumber>
      </_GroupStartsWith>

      <_GroupStartsWith Include="$(TestRoot)JIT\opt">
        <GroupNumber>7</GroupNumber>
      </_GroupStartsWith>

      <_GroupStartsWith Include="$(TestRoot)JIT\Regression\CLR-x86-JIT\V1-M11-Beta2">
        <GroupNumber>8</GroupNumber>
      </_GroupStartsWith>

      <_GroupStartsWith Include="$(TestRoot)JIT\SIMD">
        <GroupNumber>9</GroupNumber>
      </_GroupStartsWith>

      <_GroupStartsWith Include="$(TestRoot)Loader\classloader\TypeGeneratorTests\TypeGeneratorTest200">
        <GroupNumber>10</GroupNumber>
      </_GroupStartsWith>
    </ItemGroup>

    <PropertyGroup Condition="'$(__TestGroupToBuild)' != ''">
      <!-- This computes lower inclusive and upper exclusive boundaries for Group number $(__TestGroupToBuild). -->
      <_GroupStartsWith>@(_GroupStartsWith->WithMetadataValue("GroupNumber", $(__TestGroupToBuild)))</_GroupStartsWith>
      <_GroupEndsWithExcl>@(_GroupStartsWith->WithMetadataValue("GroupNumber", $([MSBuild]::Add($(__TestGroupToBuild), 1))))</_GroupEndsWithExcl>
    </PropertyGroup>

    <ItemGroup>
      <AllProjects>
        <InGroup>True</InGroup>
      </AllProjects>

      <AllProjects Condition=" '$(_GroupStartsWith)' != '' And $([System.StringComparer]::OrdinalIgnoreCase.Compare($(_GroupStartsWith), %(Identity))) &gt; 0 ">
        <InGroup>False</InGroup>
      </AllProjects>

      <AllProjects Condition=" '$(_GroupEndsWithExcl)' != '' And $([System.StringComparer]::OrdinalIgnoreCase.Compare(%(Identity), $(_GroupEndsWithExcl))) &gt;= 0 ">
        <InGroup>False</InGroup>
      </AllProjects>
    </ItemGroup>

    <ItemGroup>
      <Project Include="@(AllProjects->WithMetadataValue('InGroup', 'True'))">
        <AdditionalProperties>TargetOS=$(TargetOS)</AdditionalProperties>
      </Project>
    </ItemGroup>

    <Message Importance="High" Text="Number of test projects total: @(Project->Count())" Condition="'$(__TestGroupToBuild)' == ''" />
    <Message Importance="High" Text="Number of test projects in group $(__TestGroupToBuild): @(Project->Count())" Condition="'$(__TestGroupToBuild)' != ''" />

  </Target>

  <Import Project="$(MSBuildThisFileDirectory)dir.traversal.targets" />

  <!-- Override clean from dir.traversal.targets and just remove the full TestBinDir -->
  <Target Name="Clean">
    <RemoveDir Directories="$(TestBinDir)" />
  </Target>
</Project>
